﻿using System;
using System.Text;
using System.Reflection;
using System.Data;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using Ice.Lib.Framework;
using Ice.UI.FormFunctions;
using Ice.Core;
using System.Net.Mail;
using System.Net;
using System.Diagnostics;
using Infragistics.Win.UltraWinToolbars;
using Ice.Adapters;
using System.Collections;
using Ice.Lib.Searches;
using Ice.BO;
using System.Security.Cryptography;
using Epicor.IME;
using Ice.Lib.Customization;

namespace Epicor.Pub
{
    /// <summary>公共方法</summary>
    public class PubFun
    {
        /// <summary>配置</summary>
        public static PubConfig Conf = new PubConfig();
        /// <summary>代码提示</summary>
        public static IMEMain ime = null;
        #region Epicor常用方法
        /// <summary>使用配置文件登录Epicor </summary>
        public static Session Login(string confPath, string user, string password, string company = "", Session.LicenseType licenseType = Session.LicenseType.Default)
        {
            return PubUser.Login(confPath, user, password, company, licenseType);
        }
        /// <summary>按GUID获取Epicor控件</summary>
        public static T GetControlByGuid<T>(CustomScriptManager csm,string guid)
        {
            return (T)(Object)csm.GetNativeControlReference(guid);
        }

        /// <summary>设置面板顺序(Key)</summary>
        public static void SetTabIndex(CustomScriptManager csm, string parentPanelGuid,string tabKey,int index)
        {
            EpiDockManagerPanel dmp = GetControlByGuid<EpiDockManagerPanel>(csm, parentPanelGuid);
            for (int i = 0; i < dmp.baseDockManager.DockAreas[0].Panes.Count; i++)
            {
                Infragistics.Win.UltraWinDock.DockablePaneBase pane = dmp.baseDockManager.DockAreas[0].Panes[i];
                if (pane.Key == tabKey)
                {
                    dmp.baseDockManager.DockAreas[0].Panes.RemoveAt(i);
                    dmp.baseDockManager.DockAreas[0].Panes.Insert(pane, index);
                    break;
                }
            }
        }
        /// <summary>设置面板顺序(Index)</summary>
        public static void SetTabIndex(CustomScriptManager csm, string parentPanelGuid, int index1, int index)
        {
            EpiDockManagerPanel dmp = GetControlByGuid<EpiDockManagerPanel>(csm, parentPanelGuid);
            Infragistics.Win.UltraWinDock.DockablePaneBase pane = dmp.baseDockManager.DockAreas[0].Panes[index1];
            dmp.baseDockManager.DockAreas[0].Panes.RemoveAt(index1);
            dmp.baseDockManager.DockAreas[0].Panes.Insert(pane, index);
        }

        /// <summary>使用listLookup获取adapter数据</summary>
        public static DataTable GetAdapterData(EpiTransaction otran, string AdapterN, string whereClause = "", Boolean showSeach = false, Boolean multiSelect = true)
        {
            Boolean recSelected;
            DataSet dsAdapter = SearchFunctions.listLookup(otran, AdapterN, out recSelected, showSeach, whereClause, multiSelect);
            DataTable dt = new DataTable();
            if (recSelected)
            {
                dt = dsAdapter.Tables[0];
            }
            return dt;
        }

        /// <summary>从BAQ获取数据</summary>
        public static DataTable GetBAQData(EpiTransaction otrans, string queryID, bool clearWhere = false, BAQWhereItem[] queryWhere = null)
        {
            DataTable dt = null;
            DynamicQueryAdapter dqa = new DynamicQueryAdapter(otrans);
            try
            {
                dqa.BOConnect();
                bool bl = dqa.GetByID(queryID);

                if (bl)
                {
                    if (clearWhere) dqa.QueryDesignData.QueryWhereItem.Clear();
                    if (queryWhere != null)
                    {
                        for (int r = 0; r < queryWhere.Length; r++)
                        {
                            DynamicQueryDataSet.QueryWhereItemRow row1 = queryWhere[r].GetNewQueryWhereItemRow(dqa);
                            dqa.QueryDesignData.QueryWhereItem.Rows.Add(row1);
                        }
                    }
                    QueryExecutionDataSet qed = new QueryExecutionDataSet();
                    dqa.Execute(dqa.QueryDesignData, qed);
                    dt = dqa.QueryResults.Tables[0];
                }
            }
            catch 
            {
               
            }
            finally
            {
                dqa.Dispose();
            }
            return dt;
        }

        /// <summary> 调用BAQ报表界面 </summary>
        public static void OpenBAQReportForm(EpiTransaction otran, string BAQReportName, KeyValue[] list)
        {
            try
            {
                LaunchFormOptions lfo = new LaunchFormOptions();
                lfo.ValueIn = BAQReportName;
                UIReflector BAQForm = ProcessCaller.LaunchCallbackForm(otran, "Ice.UIRpt.BAQReport", lfo);
                EpiDataView ParamView = (EpiDataView)BAQForm.UITrans.EpiDataViews["ReportParam"];
                if (list != null)
                {
                    ParamView.dataView[ParamView.Row].BeginEdit();
                    for (int i = 0; i < list.Length; i++)
                    {
                        ParamView.dataView[ParamView.Row][list[i].Key] = list[i].Value;//传递参数到BAQ报表
                    }
                    ParamView.dataView[ParamView.Row].EndEdit();
                }
                BAQForm.UITrans.NotifyAll();
            }
            catch (Exception e)
            {
                throw new Exception("调用BAQ报表界面错误！" + e.Message);
            }
        }

        /// <summary>打开菜单</summary>
        public static void OpenMenu(EpiTransaction otrans, string menuID, string valueIn = "")
        {
            LaunchFormOptions opts = new LaunchFormOptions();
            opts.ValueIn = valueIn;
            ProcessCaller.LaunchForm(otrans, menuID, opts);
        }

        /// <summary>根据类名打开窗体</summary>
        public static UIReflector OpenForm(EpiTransaction otrans, string assemblyName, string valueIn = "", bool suppress = false)
        {
            LaunchFormOptions opts = new LaunchFormOptions();
            opts.IsModal = suppress;
            opts.SuppressFormSearch = suppress;
            opts.ValueIn = valueIn;
            return ProcessCaller.LaunchCallbackForm(otrans, assemblyName, opts);
        }

        /// <summary></summary>
        public static SearchOptions GetSearchOptions(KeyValue[] kv)
        {
            Hashtable wcHash = new Hashtable();
            for(int i = 0; i < kv.Length; i++)
            {
                wcHash.Add(kv[i].Key, kv[i].Value);
            }
            SearchOptions opts = SearchOptions.CreateRuntimeSearch(wcHash, DataSetMode.RowsDataSet);
            return opts;
        }

        ///// <summary>调用系统方法显示水晶报表</summary>
        //public static void ViewCrystalReport(EpiTransaction otran,DataSet ds, string rptName, string rptTitle = null)
        //{
        //    try
        //    {
        //        if (rptTitle == null) rptTitle = rptName;
        //        if (!Directory.Exists(Application.StartupPath + @"\Temp"))
        //        {
        //            Directory.CreateDirectory(Application.StartupPath + @"\Temp");
        //        }
        //        ds.WriteXml(Application.StartupPath + @"\Temp\" + rptName + ".xml", XmlWriteMode.WriteSchema);
        //        ds.WriteXml(Application.StartupPath + @"\Temp\" + rptName + "_1.xml", XmlWriteMode.WriteSchema);
        //        //MessageBox.Show(Application.StartupPath + @"\Temp\" + rptName + ".xml");
        //        File.Copy(GetServersPath(GetServerName(otran)) + @"\reports\CustomReports\" + rptName + ".rpt", Application.StartupPath + @"\Temp\" + rptName + ".rpt", true);
        //        for (int x = 1; x <= 1000; x++)
        //        {
        //            Application.DoEvents();
        //            System.Threading.Thread.Sleep(30);
        //        }
        //        if (EpiCrystalReport.IsRequiredCrystalRuntimeInstalled())
        //        {
        //            //会删除这两个文件
        //            EpiCrystalViewer Viewer = new EpiCrystalViewer(Application.StartupPath + @"\Temp\" + rptName + ".rpt", Application.StartupPath + @"\Temp\" + rptName + ".xml", rptTitle);
        //            Viewer.Show();
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        throw new Exception("ViewReport错误！" + e.Message);
        //    }
        //}

        /// <summary> EpiDataView添加新字段</summary>
        public static void EpiDataViewAddColumns(EpiDataView edv, PubColumn[] columns, string languageID = "sch")
        {
            for (int i = 0; i < columns.Length; i++)
            {
                DataColumn dc = new DataColumn(columns[i].ColumnName, columns[i].ColumnType);
                if(languageID=="sch") dc.Caption = columns[i].ColumnCaptionSch;
                else  dc.Caption = columns[i].ColumnCaptionEng;
                edv.dataView.Table.Columns.Add(dc);
            }
        }
        /// <summary> 初始化EpiUltraGrid字段</summary>
        public static DataTable InitEpiUltraGrid(EpiUltraGrid ug1, PubColumn[] columns, string languageID = "sch")
        {
           
            DataTable dt = new DataTable();
            for (int i = 0; i < columns.Length; i++)
            {
                dt.Columns.Add(columns[i].ColumnName, columns[i].ColumnType);
            }
            ug1.DataSource = dt;
            for (int i = 0; i < columns.Length; i++)
            {
                if (languageID.ToLower() == "sch")
                {
                    ug1.DisplayLayout.Bands[0].Columns[columns[i].ColumnName].Header.Caption = columns[i].ColumnCaptionSch;
                }
                else
                {
                    ug1.DisplayLayout.Bands[0].Columns[columns[i].ColumnName].Header.Caption = columns[i].ColumnCaptionEng;
                }
                ug1.DisplayLayout.Bands[0].Columns[columns[i].ColumnName].Width = columns[i].ColumnWidth;
                ug1.DisplayLayout.Bands[0].Columns[columns[i].ColumnName].Hidden = columns[i].Hidden;
                ug1.DisplayLayout.Bands[0].Columns[columns[i].ColumnName].CellAppearance.TextVAlign = Infragistics.Win.VAlign.Middle;
                if (!columns[i].AllowEdit)
                {
                    ug1.DisplayLayout.Bands[0].Columns[columns[i].ColumnName].CellActivation = Infragistics.Win.UltraWinGrid.Activation.NoEdit;
                    ug1.DisplayLayout.Bands[0].Columns[columns[i].ColumnName].CellAppearance.BackColor = Color.Gray;//Lavender'Gray'DarkGray,LightGray
                }
                if (columns[i].ColumnType == typeof(decimal))
                {
                    InitEpiUGNumber(ug1, columns[i].ColumnName, columns[i].ColumnDigits);
                }
            }
            return dt;
        }

        /// <summary> 初始化EpiUltraGrid字段下拉列表</summary>
        public static void InitEpiUltraGridDDL(EpiUltraGrid ug1, string colName, DataTable dt, string valueColName, string textColName = null, int type = 0)
        {
            if (textColName == null)
            {
                textColName = valueColName;
            }
            if (ug1.DisplayLayout.ValueLists.Exists(colName))
            {
                ug1.DisplayLayout.ValueLists[colName].ValueListItems.Clear();
            }
            else
            {
                ug1.DisplayLayout.ValueLists.Add(colName);
            }
            Infragistics.Win.ValueListItem[] list = new Infragistics.Win.ValueListItem[dt.Rows.Count];
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                switch (type)
                {
                    case 1:
                        list[i] = new Infragistics.Win.ValueListItem(dt.Rows[i][valueColName],
                            Convert.ToString(dt.Rows[i][valueColName]) + "(" + Convert.ToString(dt.Rows[i][textColName]) + ")");
                        break;
                    default:
                        list[i] = new Infragistics.Win.ValueListItem(dt.Rows[i][valueColName], Convert.ToString(dt.Rows[i][textColName]));
                        break;
                } 
            }
            ug1.DisplayLayout.ValueLists[colName].ValueListItems.AddRange(list);
            ug1.DisplayLayout.ValueLists[colName].DisplayStyle = Infragistics.Win.ValueListDisplayStyle.DisplayText;
            ug1.DisplayLayout.Bands[0].Columns[colName].Style = Infragistics.Win.UltraWinGrid.ColumnStyle.DropDown;
            ug1.DisplayLayout.Bands[0].Columns[colName].ValueList = ug1.DisplayLayout.ValueLists[colName];
        }
        /// <summary> 初始化EpiUltraGrid数字字段</summary>
        public static void InitEpiUGNumber(EpiUltraGrid ug1, string colName, int n = 0)
        {
            string str1 = "#,###,###,##0";
            for (int i = 0; i < n; i++)
            {
                if (i == 0)
                {
                    str1 += ".";
                }
                str1 += "0";
            }
            ug1.DisplayLayout.Bands[0].Columns[colName].Format = str1;
            ug1.DisplayLayout.Bands[0].Columns[colName].CellAppearance.TextHAlign = Infragistics.Win.HAlign.Right;
        }

        /// <summary> 初始化EpiNumericEditor数据格式</summary>
        public static void InitEpiNumericEditor(EpiNumericEditor epiNE, int n = 0)
        {
            string str1 = "#,###,###,##0";
            string str2 = "-n,nnn,nnn,nnn";
            for (int i = 0; i < n; i++)
            {
                if (i == 0)
                {
                    str1 += ".";
                    str2 += ".";
                }
                str1 += "0";
                str2 += "n";
            }
            epiNE.FormatString = str1;
            epiNE.MaskInput = str2;
            epiNE.NumericType = Infragistics.Win.UltraWinEditors.NumericType.Decimal;
        }

        /// <summary> 初始化EpiNumericEditor数据格式</summary>
        public static void InitEpiDateTimeEditor(EpiDateTimeEditor epiDTE)
        {
            epiDTE.MaskInput = "yyyy/mm/dd";
            epiDTE.FormatString = "yyyy/MM/dd";
        }

        /// <summary> EpiDataView设置columns只读</summary>
        public static void SetEDVReadOnly(EpiDataView edv, string[] columns)
        {
            for (int i = 0; i < columns.Length; i++)
            {
                if (edv.dataView.Table.Columns.Contains(columns[i]))
                {
                    edv.dataView.Table.Columns[columns[i]].ExtendedProperties["ReadOnly"] = true;
                }
            }
        }
		
        /// <summary> EpiDataView设置columns隐藏</summary>
        public static void SetEDVHidden(EpiDataView edv, string[] columns)
        {
            for (int i = 0; i < columns.Length; i++)
            {
                if (edv.dataView.Table.Columns.Contains(columns[i]))
                {
                    edv.dataView.Table.Columns[columns[i]].ExtendedProperties["IsHidden"] = true;
                }
            }
        }
        /// <summary> EpiDataView设置columns显示</summary>
        public static void SetEDVDisplay(EpiDataView edv, string[] columns)
        {
            for (int i = 0; i < edv.dataView.Table.Columns.Count; i++)
            {
                edv.dataView.Table.Columns[i].ExtendedProperties["IsHidden"] = !((IList)columns).Contains(edv.dataView.Table.Columns[i].ColumnName);

            }
        }
        /// <summary>发送邮件</summary>
        public static bool SendEmail(string FromAddr, string ReplyToAddr, string ToAddrs, string CCAddrs, string Subject, string Body)
        {
            try
            {
                SmtpClient smtp = new SmtpClient(); //实例化一个SmtpClient
                smtp.DeliveryMethod = SmtpDeliveryMethod.Network; //将smtp的出站方式设为 Network
                smtp.EnableSsl = true;//smtp服务器是否启用SSL加密
                smtp.Host = Conf.SMTP_Host; //指定 smtp 服务器地址
                smtp.Port = Conf.SMTP_Port; //指定 smtp 服务器的端口，默认是25，如果采用默认端口，可省去
                //如果你的SMTP服务器不需要身份认证，则使用下面设置为true，不过，目前基本没有不需要认证的了
                smtp.UseDefaultCredentials = false;
                //如果需要认证，则用下面的方式
                smtp.Credentials = new NetworkCredential(Conf.SMTP_UserName, Conf.SMTP_Password);
                MailMessage mm = new MailMessage(); //实例化一个邮件类
                mm.Priority = MailPriority.Normal; //邮件的优先级，分为 Low, Normal, High，通常用 Normal即可
                mm.From = new MailAddress(FromAddr, FromAddr, Encoding.GetEncoding(936));
                mm.ReplyToList.Add(new MailAddress(ReplyToAddr, ReplyToAddr, Encoding.GetEncoding(936)));
                mm.To.Add(ToAddrs);
                if (CCAddrs != "")
                {
                    mm.CC.Add(CCAddrs);
                }
                mm.SubjectEncoding = Encoding.GetEncoding(936);
                mm.IsBodyHtml = true; //邮件正文是否是HTML格式
                mm.BodyEncoding = Encoding.GetEncoding(936);
                mm.Subject = Subject;
                String s = Body;
                s = s.Replace("\n", "<br>");
                s = s.Replace(" ", "&nbsp;");
                mm.Body = s;
                //mm.Attachments.Add(new Attachment(@fileName));
                smtp.Send(mm);
                return true;
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
                return false;
            }
        }

        /// <summary>隐藏UD界面左边面板</summary>
        public static void HiddenUDLeftPanel(EpiBaseForm form, string[] hiddenControls = null)
        {
            if (hiddenControls == null)
            {
                hiddenControls = new string[] { "dockableWindows3", "_SonomaFormUnpinnedTabAreaLeft" };
            }
            for (int i = 0; i < form.Controls.Count; i++)
            {
                if (Array.IndexOf(hiddenControls, form.Controls[i].Name) >= 0)
                {
                    form.Controls[i].Visible = false;
                }
            }
        }

        /// <summary>隐藏工具栏中新建,删除,保存工具</summary>
        public static void HiddenToolbars(EpiBaseForm form, string[] tools = null)
        {
            if (tools == null)
            {
                tools = new string[] { "NewTool", "NewMenuTool", "DeleteTool", "SaveTool" };
            }
            UltraToolbarsManager BaseToolbarsManager = (UltraToolbarsManager)(form.GetType().InvokeMember("baseToolbarsManager", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance, null, form, null));
            for (var i = 0; i < tools.Length; i++)
            {
                BaseToolbarsManager.Tools[tools[i]].SharedProps.Visible = false;
                BaseToolbarsManager.Tools[tools[i]].SharedProps.Enabled = false;
            }
        }

        /// <summary>绑定DataTable数据到EpiUltraCombo控件</summary>
        public static void LoadDropDown(EpiUltraCombo comControl, DataTable dt, string valueColName, string displayColName)
        {
            string[] columns = new string[dt.Columns.Count];
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                columns[i] = dt.Columns[i].ColumnName;
            }
            comControl.ValueMember = valueColName;
            comControl.DataSource = dt.DefaultView.ToTable(true, columns);
            comControl.DisplayMember = displayColName;
            string[] fields = new string[] { displayColName };
            comControl.SetColumnFilter(fields);
        }

        #endregion

        #region 一般方法
        /// <summary>初始化IME </summary>
        public static void InitIME(object _this)
        {
            if (ime != null) ime.Dispose();
            ime = new IMEMain(_this);
            ime.imeFun.WaitHashAdd("Epicor.Pub.dll");
        }

        /// <summary> 获取数据库连接字符串 </summary>
        public static string GetConnStr()
        {
            //string DBName = PubFun.GetServerName(otran).ToUpper();
            ////如果数据库名称和服务名称不同
            //switch (DBName)
            //{
            //    case "DEMO1015":
            //        DBName = "DemoDB";
            //        break;
            //    default:
            //        throw new Exception("获取数据库名称失败!");
            //}
            return String.Format("Initial Catalog={0};Data Source={1};User ID={2};Password={3}", Conf.DB_Name, Conf.DB_IP, Conf.DB_UserID, Conf.DB_Password);
        }

        /// <summary>弹出一个消息框</summary>
        public static void MsgShow(string Value, string title = "", int Width = 300, int Height = 120)
        {
            Form form1 = new Form();
            form1.Size = new Size(Width, Height);
            form1.StartPosition = FormStartPosition.CenterScreen;
            form1.Text = title;
            form1.MaximizeBox = false;
            form1.MinimizeBox = false;
            if (File.Exists(Application.StartupPath + @"\epicor.ico"))
            {
                form1.Icon = new Icon(Application.StartupPath + @"\epicor.ico", 16, 16);
            }
            TextBox tb1 = new TextBox();
            tb1.Multiline = true;
            tb1.ScrollBars = ScrollBars.Vertical;
            tb1.Dock = DockStyle.Fill;
            tb1.Name = "textbox1";
            tb1.Text = Value;
            form1.Controls.Add(tb1);
            form1.ShowDialog();
        }

        private static ViewForm vf = null;
        /// <summary>弹出一个窗口显示数据</summary>
        public static void DebugData(KeyValue[] data)
        {
            if (vf == null || vf.Visible == false)
            {
                vf = new ViewForm();
                vf.Show();
            }
            vf.LoadData(data);
        }

        /// <summary>连接共享文件夹</summary>
        public static bool ConnectPath(string path, string userName = "", string passWord = "")
        {
            bool Flag = false;
            Process proc = new Process();
            try
            {
                proc.StartInfo.FileName = "cmd.exe";
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardInput = true;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.CreateNoWindow = true;
                proc.Start();
                string dosLine = @"net use " + path + " /User:" + userName + " " + passWord + " /PERSISTENT:YES";
                proc.StandardInput.WriteLine(dosLine);
                proc.StandardInput.WriteLine("exit");
                while (!proc.HasExited)
                {
                    proc.WaitForExit(1000);
                }
                string errormsg = proc.StandardError.ReadToEnd();
                proc.StandardError.Close();
                if (string.IsNullOrEmpty(errormsg))
                {
                    Flag = true;
                }
                else
                {
                    throw new Exception(errormsg);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                proc.Close();
                proc.Dispose();
            }
            return Flag;
        }
        /// <summary>从fromDT复制相同列名的数据到toDT</summary>
        public static void CopyTable(DataTable fromDT, DataTable toDT)
        {
            for (int r = 0; r < fromDT.Rows.Count; r++)
            {
                DataRow dr = toDT.NewRow();
                for (int i = 0; i < toDT.Columns.Count; i++)
                {
                    string columnName = toDT.Columns[i].ColumnName;
                    if (fromDT.Columns.Contains(columnName))
                    {
                        dr[columnName] = fromDT.Rows[r][columnName];
                    }
                }
                toDT.Rows.Add(dr);
            }
        }

        ///// <summary>获取服务器文件路径</summary>
        //public static string GetServersPath(string ServerName)
        //{
        //    return @"\\" + PubData.Server_IP + @"\wwwroot\" + ServerName + @"\Server";
        //}
        /// <summary>treeNode加载dt数据</summary>
        //public static void LoadTreeNode(TreeNode treeNode, DataTable dt, string pKey)
        //{
        //    DataRow[] drs = dt.Select("pKey='" + pKey + "'");
        //    for (int i = 0; i < drs.Length; i++)
        //    {
        //        TreeNode treeNode1 = new TreeNode()
        //        {
        //            Name = drs[i]["Name"].ToString()
        //            ,
        //            Text = drs[i]["Text"].ToString()
        //            ,
        //            Tag = drs[i]
        //        };
        //        treeNode.Nodes.Add(treeNode1);
        //        LoadTreeNode(treeNode1, dt, drs[0]["Key"].ToString());
        //    }
        //}


        ///// <summary>含税价格转未税价格(priceTax:含税价格,tax:税率)</summary>
        //public static decimal ConvertPrice(decimal priceTax, decimal tax)
        //{
        //    return priceTax / (1 + tax);
        //}
        private static byte[] buffer2 = new byte[] { 0x66, 0x10, 0x5d, 0x9c, 0x4e, 4, 0xda, 0x20 };
        private static byte[] buffer3 = new byte[] { 0x66, 0x10, 0x5d, 0x9c, 0x4e, 4, 0xda, 0x20 };       
        /// <summary>MD5加密</summary>
        public static string Md5Encrypt(string strSource)
        {
            if (string.IsNullOrEmpty(strSource)) return strSource;
            byte[] bytes = Encoding.Default.GetBytes(strSource);
            ICryptoTransform transform = new DESCryptoServiceProvider { Key = buffer2, IV = buffer3 }.CreateEncryptor();
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write);
            stream2.Write(bytes, 0, bytes.Length);
            stream2.FlushFinalBlock();
            return Convert.ToBase64String(stream.ToArray());
        }
        /// <summary>MD5解密</summary>
        public static string Md5Decrypt(string Source)
        {
            if (string.IsNullOrEmpty(Source) )return Source;
            byte[] buffer = Convert.FromBase64String(Source);
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider { Key = buffer2, IV = buffer3 };
            MemoryStream stream = new MemoryStream(buffer, 0, buffer.Length);
            ICryptoTransform transform = provider.CreateDecryptor();
            CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Read);
            StreamReader reader = new StreamReader(stream2, Encoding.Default);
            return reader.ReadToEnd();
        }
        #endregion

        #region 反射调用BO功能
        /// <summary>给物料新增仓库(反射) </summary>
        public static void NewPartWhse(EpiTransaction otran, string partnum, string warehouse, string binnum = null)
        {
            PubAdapter adp = new PubAdapter(otran, "Part");
            try
            {
                adp.BOConnect();
                bool bl = adp.GetByID(new object[] { partnum }, new Type[] { typeof(string) });
                if (bl)
                {
                    DataSet ds1 = adp.GetCurrentDataSet();
                    string sPlant = ds1.Tables["PartPlant"].Rows[0]["Plant"].ToString();
                    if (ds1.Tables["PartWhse"].Select("WarehouseCode='" + warehouse + "'").Length > 0)
                    {
                        Debug.Print("仓库已经存在!");
                    }
                    else
                    {
                        bool bl1 = (bool)adp.InvokeFun("GetNewPartWhse", new object[] { partnum, sPlant }, new Type[] { typeof(string), typeof(string) });
                        ds1 = adp.GetCurrentDataSet();
                        if (bl1)
                        {
                            int r = ds1.Tables["PartWhse"].Rows.Count - 1;
                            ds1.Tables["PartWhse"].Rows[r]["WarehouseCode"] = warehouse;
                            if (!string.IsNullOrEmpty(binnum)) ds1.Tables["PartWhse"].Rows[r]["PrimBinNum"] = binnum;
                            adp.Update();
                        }
                    }
                }
            }
            finally
            {
                adp.Dispose();
            }
        }

        /// <summary> 调用快速搜索界面(反射) </summary>
        public static object OpenQuickSearchForm(EpiTransaction otrans, string QuickSearchID, bool multiSelect = false, int pageSize = 0, DataTable ControlSetting = null)
        {
            PubAdapter adp = new PubAdapter(otrans, "QuickSearch");
            object obj = null;
            try
            {
                adp.BOConnect();
                obj = adp.InvokeFun("ShowQuickSearchForm", new object[] { otrans, QuickSearchID, multiSelect, pageSize, ControlSetting }, new Type[] { typeof(EpiTransaction), typeof(string), typeof(bool), typeof(int), typeof(DataTable) });
            }
            finally
            {
                adp.Dispose();
            }
            return obj;
        }

        /// <summary>计算CTP,从SO生成PO(反射) </summary>
        public static bool CalculateCTP(EpiTransaction otrans,int orderNum) {
            PubAdapter adp = new PubAdapter(otrans, "CapPromise");
            bool result = true;
            try
            {
                adp.BOConnect();
                bool bl = (bool)adp.InvokeFun("GetNewCapPromise", new object[] { orderNum }, new Type[] { typeof(int) });
                if (bl)
                {
                    bool lDemandEntry = false;
                    string outMessage = "";
                    DateTime startDate = DateTime.Now;
                    DataSet ds1 = adp.GetCurrentDataSet();
                    ds1.Tables["PartPlant"].Rows[0]["Plant"] = startDate;
                    string sPlant = ds1.Tables["CapPromise"].Rows[0]["ProjectedStartDate"].ToString();
                    for (int r = 0; r < ds1.Tables["CapPromiseDtl"].Rows.Count; r++) {
                        ds1.Tables["CapPromiseDtl"].Rows[r]["ProposedStartDate"] = startDate;
                        ds1.Tables["CapPromiseDtl"].Rows[r]["CTP"] = true;
                    }
                    object CapPromiseData = adp.GetValue("CapPromiseData");
                    adp.InvokeFun("CalculateCTP", new object[] { lDemandEntry, outMessage , CapPromiseData }, new Type[] { typeof(bool), typeof(string), CapPromiseData.GetType() });
                    for (int r = 0; r < ds1.Tables["CapPromiseDtl"].Rows.Count; r++)
                    {
                        ds1.Tables["CapPromiseDtl"].Rows[r]["Confirm"] = true;
                    }
                    string opError="";
                    adp.InvokeFun("ConfirmCTP", new object[] { opError }, new Type[] { typeof(string) });
                }
            }
            catch  {
                result = false;
            }
            finally
            {
                adp.Dispose();
            }
            return result;
        }

        ///<summary>根据多公司间采购建议,生成公司间的SO(反射) </summary>
        public static bool SOPOLink(EpiTransaction otrans)
        {
            PubAdapter adp = new PubAdapter(otrans, "SOPOLink");
            bool result = true;
            try
            {
                adp.BOConnect();
                bool morePages = false;
                string whereClause = "IncomingOutgoing = 'I' AND Action='Add'";
                SearchOptions opts = new SearchOptions(SearchMode.AutoSearch);
                opts.NamedSearch.WhereClauses.Add("IMOrderHed", whereClause);
                DataTable dt = ((DataSet)adp.InvokeFun("GetList", new object[] { opts, morePages }, new Type[] { typeof(SearchOptions), typeof(bool) })).Tables[0].Copy();
                string bz = "I";
                int icPONum;
                int intQueID;
                string extCompany;
                for (int r = 0; r < dt.Rows.Count; r++) {
                    icPONum = Convert.ToInt32(dt.Rows[r]["PONum"]);
                    extCompany = Convert.ToString(dt.Rows[r]["ExtCompany"]);
                    intQueID = Convert.ToInt32(dt.Rows[r]["intQueID"]);
                    adp.ClearData();
                    bool bl= (bool)adp.InvokeFun("CustomGetByID", new object[] { bz, icPONum, intQueID }, new Type[] { typeof(string), typeof(int), typeof(int) });
                    if (bl) {
                        int iOrderNum = 0;
                        int iOrderLine = 0;
                        int pageSize = 1;
                        int absolutePage = 1;
                        morePages = false;
                        adp.InvokeFun("GetOrderDtl", new object[] { iOrderNum, iOrderLine, pageSize, absolutePage, morePages }, new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(bool) });
                        int iSeqNum = 0;
                        adp.InvokeFun("GetOrderMsc", new object[] { iOrderNum, iOrderLine, iSeqNum, pageSize, absolutePage, morePages }, new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(bool) });
                        int iOrderRelNum = 0;
                        adp.InvokeFun("GetOrderRel", new object[] { iOrderNum, iOrderLine, iOrderRelNum, pageSize, absolutePage, morePages }, new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(bool) });
                        bool lChildUnitPricesDiffer = false;
                        decimal dIntQueID = intQueID;
                        string cUnitPricesDifferMessage = "";
                        string cCurrenciesDifferMessage = "";
                        string cUOMDifferMessage = "";
                        adp.InvokeFun("CheckSOPODifferences", new object[] { lChildUnitPricesDiffer, dIntQueID, cUnitPricesDifferMessage, cCurrenciesDifferMessage, cUOMDifferMessage }, new Type[] { typeof(bool), typeof(decimal), typeof(string), typeof(string), typeof(string) });
                        string cGlbPartQuestionText = "";
                        string cPricesDifferQuestionText = "";
                        adp.InvokeFun("CheckReadyForOrder", new object[] { dIntQueID, lChildUnitPricesDiffer, cGlbPartQuestionText, cPricesDifferQuestionText }, new Type[] {  typeof(decimal),typeof(bool), typeof(string), typeof(string) });
                        DataSet ds1 = adp.GetCurrentDataSet();
                        ds1.Tables["IMOrderHed"].Rows[0]["ReadyForOrder"] = true;
                        adp.Update();
                        bool needsConfig = false;
                        adp.InvokeFun("ProcessSuggestions", new object[] { needsConfig }, new Type[] {  typeof(bool)});
                    }
                }
            }
            catch
            {
                result = false;
            }
            finally
            {
                adp.Dispose();
            }
            return result;
        }

        ///<summary>批量工单发料(反射)</summary>
        public static int IssueJobMTLMass(EpiTransaction otrans, DataTable dt)
        {
            PubAdapter adp = new PubAdapter(otrans, "IssueReturn");
            int num = 0;
            try
            {
                adp.BOConnect();
                PubColumn[] DCol = PubDataModel.IssueJobMTL();
                string checkMsg = PubDataModel.CheckColumn(DCol, dt);
                if (!string.IsNullOrEmpty(checkMsg)) throw new Exception("工单发料" + checkMsg);
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    try
                    {
                        DataRow dr = dt.Rows[i];
                        adp.ClearData();
                        adp.InvokeFun("GetNewIssueReturn", new object[] { "STK-MTL", new Guid(), "MassIssueForm" }, new Type[] { typeof(string), typeof(Guid), typeof(string) });
                        DataSet ds1 = adp.GetCurrentDataSet();
                        ds1.Tables["IssueReturn"].Rows[0].BeginEdit();
                        for (int c = 0; c < DCol.Length; c++)
                        {
                            string colName = DCol[c].ColumnName;
                            if(Convert.ToString(dr[colName])!="")ds1.Tables["IssueReturn"].Rows[0][colName] = dr[colName];
                        }
                        ds1.Tables["IssueReturn"].Rows[0]["IssuedComplete"] = true;
                        ds1.Tables["IssueReturn"].Rows[0].EndEdit();
                        adp.InvokeFun("OnChangingToJobSeq", new object[] { dr["ToJobSeq"] }, new Type[] { typeof(int) });
                        string pcMessage = "";
                        adp.InvokeFun("OnChangeToJobSeq", new object[] { "IssueMaterial", pcMessage }, new Type[] { typeof(string), typeof(string).MakeByRefType() });
                        bool requiresUserInput = false;
                        adp.InvokeFun("PrePerformMaterialMovement", new object[] { requiresUserInput }, new Type[] { typeof(bool).MakeByRefType() });
                        string pcNeqQtyAction = "";
                        adp.InvokeFun("NegativeInventoryTest", new object[] { dr["PartNum"], dr["FromWarehouseCode"], dr["FromBinNum"], (dr["LotNum"] is DBNull)?"": dr["LotNum"], dr.Table.Columns.Contains("PCID") ? dr["PCID"] : "", dr["UM"], dr.Table.Columns.Contains("DimConvFactor") ? dr["DimConvFactor"] : Convert.ToDecimal(1), dr["TranQty"], pcNeqQtyAction, pcMessage }, new Type[] { typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(decimal), typeof(decimal), typeof(string).MakeByRefType(), typeof(string).MakeByRefType() });
                        string legalNumberMessage = "";
                        string partTranPKs = "";
                        adp.InvokeFun("PerformMaterialMovement", new object[] { true, legalNumberMessage, partTranPKs }, new Type[] { typeof(bool), typeof(string).MakeByRefType(), typeof(string).MakeByRefType() });
                        num++;
                    }
                    catch (Exception e1)
                    {
                        dt.Rows[i]["ResultMsg"] = e1.Message;
                    }
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
            finally
            {
                adp.Dispose();
            }
            return num;
        }
        ///<summary>批量工单退料(反射)</summary>
        public static int ReturnJobMTLMass(EpiTransaction otrans, DataTable dt)
        {
            PubAdapter adp = new PubAdapter(otrans, "IssueReturn");
            int num = 0;
            try
            {
                adp.BOConnect();
                PubColumn[] DCol = PubDataModel.ReturnJobMTL();
                string checkMsg = PubDataModel.CheckColumn(DCol, dt);
                if (!string.IsNullOrEmpty(checkMsg)) throw new Exception("工单退料" + checkMsg);
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    try
                    {
                        DataRow dr = dt.Rows[i];
                        adp.ClearData();
                        adp.InvokeFun("GetNewIssueReturn", new object[] { "MTL-STK", new Guid(), "ReturnMaterial" }, new Type[] { typeof(string), typeof(Guid), typeof(string) });

                        DataSet ds1 = adp.GetCurrentDataSet();
                        ds1.Tables["IssueReturn"].Rows[0].BeginEdit();
                        for (int c = 0; c < DCol.Length; c++)
                        {
                            string colName = DCol[c].ColumnName;
                            if (Convert.ToString(dr[colName]) != "") ds1.Tables["IssueReturn"].Rows[0][colName] = dr[colName];
                        }
                        ds1.Tables["IssueReturn"].Rows[0]["IssuedComplete"] = true;
                        ds1.Tables["IssueReturn"].Rows[0].EndEdit();
                        adp.InvokeFun("OnChangingJobSeq", new object[] { dr["FromJobSeq"], "From", "ReturnMaterial" }, new Type[] { typeof(int), typeof(string), typeof(string) });
                        string pcMessage = "";
                        adp.InvokeFun("OnChangeFromJobSeq", new object[] { "ReturnMaterial", pcMessage }, new Type[] { typeof(string), typeof(string).MakeByRefType() });
                        adp.InvokeFun("OnChangeTranQty", new object[] { dr["TranQty"] }, new Type[] { typeof(decimal) });

                        bool requiresUserInput = false;
                        adp.InvokeFun("PrePerformMaterialMovement", new object[] { requiresUserInput }, new Type[] { typeof(bool).MakeByRefType() });
                        string legalNumberMessage = "";
                        string partTranPKs = "";
                        adp.InvokeFun("PerformMaterialMovement", new object[] { true, legalNumberMessage, partTranPKs }, new Type[] { typeof(bool), typeof(string).MakeByRefType(), typeof(string).MakeByRefType() });
                        num++;
                    }
                    catch (Exception e1)
                    {
                        dt.Rows[i]["ResultMsg"] = e1.Message;
                    }
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
            finally
            {
                adp.Dispose();
            }
            return num;
        }

        ///<summary>批量杂项发料(反射)</summary>
        public static int IssueMiscMTLMass(EpiTransaction otrans,DataTable dt)
        {
            PubAdapter adp = new PubAdapter(otrans, "IssueReturn");
            int num = 0;
            try
            {
                adp.BOConnect();
                PubColumn[] DCol =PubDataModel.IssueMiscMTL();
                string checkMsg = PubDataModel.CheckColumn(DCol, dt);
                if (!string.IsNullOrEmpty(checkMsg)) throw new Exception("杂项发料" + checkMsg);
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    try
                    {
                        DataRow dr = dt.Rows[i];
                        adp.ClearData();
                        adp.InvokeFun("GetNewPartNum", new object[] { dr["PartNum"], "STK-UKN", new Guid() }, new Type[] { typeof(string), typeof(string), typeof(Guid) });
                        DataSet ds1 = adp.GetCurrentDataSet();
                        ds1.Tables["IssueReturn"].Rows[0].BeginEdit();
                        for (int c = 0; c < DCol.Length; c++)
                        {
                            string colName = DCol[c].ColumnName;
                            if (Convert.ToString(dr[colName]) != "") ds1.Tables["IssueReturn"].Rows[0][colName] = dr[colName];
                        }
                        ds1.Tables["IssueReturn"].Rows[0]["IssuedComplete"] = true;
                        ds1.Tables["IssueReturn"].Rows[0].EndEdit();
                        adp.InvokeFun("OnChangeTranQty", new object[] { dr["TranQty"] }, new Type[] { typeof(decimal) });
                        bool requiresUserInput = false;
                        adp.InvokeFun("PrePerformMaterialMovement", new object[] { requiresUserInput }, new Type[] { typeof(bool).MakeByRefType() });
                        string pcNeqQtyAction = "";
                        string pcMessage = "";
                        adp.InvokeFun("NegativeInventoryTest", new object[] { dr["PartNum"], dr["FromWarehouseCode"], dr["FromBinNum"], (dr["LotNum"] is DBNull) ? "" : dr["LotNum"], dr.Table.Columns.Contains("PCID") ? dr["PCID"] : "", dr["UM"], dr.Table.Columns.Contains("DimConvFactor") ? dr["DimConvFactor"] : Convert.ToDecimal(1), dr["TranQty"], pcNeqQtyAction, pcMessage }, new Type[] { typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(decimal), typeof(decimal), typeof(string).MakeByRefType(), typeof(string).MakeByRefType() });
                        string legalNumberMessage = "";
                        string partTranPKs = "";
                        adp.InvokeFun("PerformMaterialMovement", new object[] { true, legalNumberMessage, partTranPKs }, new Type[] { typeof(bool), typeof(string).MakeByRefType(), typeof(string).MakeByRefType() });
                        num++;
                    }
                    catch (Exception e1)
                    {
                        dt.Rows[i]["ResultMsg"] = e1.Message;
                    }
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
            finally
            {
                adp.Dispose();
            }
            return num;

        }

        ///<summary>批量杂项退料(反射)</summary>
        public static int ReturnMiscMTLMass(EpiTransaction otrans, DataTable dt)
        {
            PubAdapter adp = new PubAdapter(otrans, "IssueReturn");
            int num = 0;
            try
            {
                adp.BOConnect();
                PubColumn[] DCol = PubDataModel.ReturnMiscMTL();
                string checkMsg = PubDataModel.CheckColumn(DCol,dt);
                if (!string.IsNullOrEmpty(checkMsg))throw new Exception("杂项退料" + checkMsg);
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    try
                    {
                        DataRow dr = dt.Rows[i];
                        adp.ClearData();
                        adp.InvokeFun("GetNewPartNum", new object[] { dr["PartNum"], "UKN-STK", new Guid() }, new Type[] { typeof(string), typeof(string), typeof(Guid) });

                        DataSet ds1 = adp.GetCurrentDataSet();
                        ds1.Tables["IssueReturn"].Rows[0].BeginEdit();
                        for (int c = 0; c < dr.Table.Columns.Count; c++)
                        {
                            string colName = dr.Table.Columns[c].ColumnName;
                            if (Convert.ToString(dr[colName]) != "") ds1.Tables["IssueReturn"].Rows[0][colName] = dr[colName];
                        }
                        ds1.Tables["IssueReturn"].Rows[0]["IssuedComplete"] = true;
                        ds1.Tables["IssueReturn"].Rows[0].EndEdit();
                        adp.InvokeFun("OnChangeTranQty", new object[] { dr["TranQty"] }, new Type[] { typeof(decimal) });
                        bool requiresUserInput = false;
                        adp.InvokeFun("PrePerformMaterialMovement", new object[] { requiresUserInput }, new Type[] { typeof(bool).MakeByRefType() });
                        string legalNumberMessage = "";
                        string partTranPKs = "";
                        adp.InvokeFun("PerformMaterialMovement", new object[] { true, legalNumberMessage, partTranPKs }, new Type[] { typeof(bool), typeof(string).MakeByRefType(), typeof(string).MakeByRefType() });
                        num++;
                    }
                    catch (Exception e1)
                    {
                        dt.Rows[i]["ResultMsg"] = e1.Message;
                    }
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
            finally
            {
                adp.Dispose();
            }
            return num;
        }
        ///<summary>添加数据(反射)</summary>
        public static int InsertData(EpiTransaction otrans, string adpName,string newFunName, DataTable dt)
        {
            PubAdapter adp = new PubAdapter(otrans, adpName);
            int result = 0;
            try
            {
                adp.BOConnect();
                for (int r1 = 0; r1 < dt.Rows.Count; r1++)
                {
                    DataRow dr = dt.Rows[r1];
                    bool bl1 = (bool)adp.InvokeFun(newFunName);
                    if (bl1)
                    {
                        DataSet ds1 = adp.GetCurrentDataSet();
                        string tableName = dt.TableName;
                        int r = ds1.Tables[tableName].Rows.Count - 1;
                        for (int c1 = 0; c1 < dt.Columns.Count; c1++) {
                            string colName = dt.Columns[c1].ColumnName;
                            if (ds1.Tables[tableName].Columns.Contains(colName))
                            {
                                ds1.Tables[tableName].Rows[r][colName] = dr[colName];
                            }
                        }
                        if (adp.Update()) result++;
                        
                    }
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
            finally
            {
                adp.Dispose();
            }
            return result;
        }

        ///<summary>删除数据(反射)</summary>
        public static bool DeleteByID(EpiTransaction otrans,string adpName, object[] obj, Type[] types)
        {
            PubAdapter adp = new PubAdapter(otrans, adpName);
            bool result = false;
            try
            {
                adp.BOConnect();
                result= adp.DeleteByID(obj, types);
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
            finally
            {
                adp.Dispose();
            }
            return result;
        }

        ///<summary>获取适配器数据(反射)</summary>
        public static DataTable GetAdapterData(EpiTransaction otrans, string adpName, SearchOptions opts, string tableName=null)
        {
            PubAdapter adp = new PubAdapter(otrans, adpName);
            DataTable dt = new DataTable();
            try
            {
                adp.BOConnect();
                DialogResult result = adp.InvokeSearch(opts);
                if (result== DialogResult.OK)
                {
                    DataSet ds1 = adp.GetCurrentDataSet();
                    if (tableName == null)
                    {
                        dt = ds1.Tables[0].Copy();
                    }
                    else {
                        dt = ds1.Tables[tableName].Copy();
                    }
                }
            }
            finally
            {
                adp.Dispose();
            }
            return dt;
        }

        #endregion
    }

}
